package org.ainlolcat.ainscience.statistics.handlers.hitran.tests;

import org.ainlolcat.ainscience.statistics.handlers.hitran.SpectrGenerator;
import org.ainlolcat.ainscience.statistics.handlers.hitran.instfunc.GaussInstrumentalFunction;
import org.ainlolcat.ainscience.statistics.handlers.hitran.instfunc.InstrumentalFunction;
import org.ainlolcat.ainscience.statistics.handlers.hitran.instfunc.InvsPolyFunction;
import org.ainlolcat.ainscience.utils.ArraysUtil;
import org.math.plot.Plot2DPanel;
import org.math.plot.Plot3DPanel;

import javax.swing.*;
import java.io.IOException;

import static java.lang.Math.sqrt;

/**
 * @author ainlolcat
 * Date: 13/11/20
 */
public class ViewDifferenceBetweenSubIntergralsAndGauss {

    public static void main(String[] args) throws IOException {
        //plotIntegrals();
        //<fParameters>0;2.26002;2595.75;0;0;2.67488</fParameters>
        //plot_aXSpectrSample(new InvsPolyFunction(0,1.953,2595.75,0,0,1.3605), 0.1);
        //plot_aXSpectrSample(new InvsPolyFunction(0,2.06015,1,0,0,1.49139), 0.1);
        //plot_aXSpectrSample(new InvsPolyFunction(0,2.26002,2595.75,0,0,2.67488), 0.2);
    }

    public static void plotIntegrals() throws IOException {
        int wSize = 50;
        double wStart = 0.01;
        double wEnd = 0.5;
        double[][] data = new double[wSize*(1+(int)((1300-1240)/0.25))][3];
        double[][] dataG = new double[wSize*(1+(int)((1300-1240)/0.25))][3];
        double[] percentage = new double[wSize];
        double[] ratio = new double[wSize];
        double[] ampRatio = new double[wSize];
        double[] I2normIRatio = new double[wSize];
        double[] gI = new double[wSize];
        double[] deltaI = new double[wSize];

        SpectrGenerator sg = new SpectrGenerator();
        double[][] spectr = sg.getAxSpectr(
                300,
                new InvsPolyFunction(0, 1.9653, 1E9, 0, 0, 1.3605),
                1240,
                1300,
                0.25
        );
        double[] x = new double[spectr.length];
        double[] y0 = new double[spectr.length];
        double[] yN;
        for (int k=0;k<x.length;k++){
            x[k]=spectr[k][0];
            y0[k]=spectr[k][1];
        }
        yN = ArraysUtil.getNormalized(y0);
        double I_N =  ArraysUtil.getNormalizedIntegral(x, yN);
        double I_0 =  ArraysUtil.getIntegral(x, y0);
        double max_0 = ArraysUtil.getMax(y0);

        System.out.println("Spectr max: " + max_0);
        System.out.println("Spectr integral: " + I_0);
        System.out.println("Spectr norm integral: " + I_N);

        for (int i=0;i<wSize;i++){
            double p = wStart + i * (wEnd - wStart) / wSize;
            percentage[i] = p;
            double[] y_sum_N = new double[spectr.length];
            double[] y_sum = new double[spectr.length];
            double[] yG_N = new double[spectr.length];
            for (int k=0;k<x.length;k++){
                yG_N[k] = p * (I_N/sqrt(2)) * new GaussInstrumentalFunction(15).getValue(Math.abs(1268-x[k]));
            }
            double[] yG = new double[spectr.length];
            for (int k=0;k<x.length;k++){
                yG[k] = p * (I_0/sqrt(2)) * new GaussInstrumentalFunction(15).getValue(Math.abs(1268-x[k]));
            }
            for (int k=0;k<x.length;k++){
                y_sum_N[k] = yN[k] + yG_N[k];
                y_sum[k] = y0[k] + yG[k];
                data[i*x.length + k][0] = p;
                data[i*x.length + k][1] = x[k];
                data[i*x.length + k][2] = y_sum_N[k];

                dataG[i*x.length + k][0] = p;
                dataG[i*x.length + k][1] = x[k];
                dataG[i*x.length + k][2] = yG_N[k];
            }
            gI[i] = ArraysUtil.getIntegral(x, yG_N);
            deltaI[i] = ArraysUtil.getNormalizedIntegral(x, y_sum_N) - I_N;
            ratio[i] =  deltaI[i] / gI[i] ;
            ampRatio[i] = max_0 / ArraysUtil.getMax(y_sum);
            I2normIRatio[i] = ArraysUtil.getIntegral(x,y_sum_N)/ArraysUtil.getNormalizedIntegral(x,y_sum_N);
        }
        print(percentage,ampRatio, "Amp ratio y over y + G");
        //print(percentage,I2normIRatio, "Ratio I/Inorm");
        //print(percentage,ratio, "Ratio delta/G");
        //print(percentage,gI, "Gauss Integral");
        //print(percentage,deltaI, "Delta");
        //print(gI,deltaI, "Delta To Gauss");

        //print3D(data, "Spectr+G");
        //print3D(dataG, "Gauss");
    }

    public static void plot_aXSpectrSample(InstrumentalFunction function, double gP) throws IOException {
        SpectrGenerator sg = new SpectrGenerator();
        double[][] spectr = sg.getAxSpectr(309, function, 1240, 1300, 0.25);
        double[] x = new double[spectr.length];
        double[] y = new double[spectr.length];
        for (int k=0;k<x.length;k++){
            x[k]=spectr[k][0];
            y[k]=spectr[k][1];
        }
        double I_0 = ArraysUtil.getIntegral(x, y);
        double[] y_sum = new double[spectr.length];
        double[] yG = new double[spectr.length];
        for (int k=0;k<x.length;k++){
            yG[k] = gP * (I_0/sqrt(2)) * new GaussInstrumentalFunction(15).getValue(Math.abs(1268-x[k]));
        }
        for (int k=0;k<x.length;k++){
            y_sum[k] = y[k] + yG[k];
        }
        print(x, y_sum, "a-X + G, p = " + gP);
    }

    public static void print3D(double[][] data, String name){
        Plot3DPanel plot2 = new Plot3DPanel();
        plot2.addScatterPlot("",data);
        JFrame frame2 = new JFrame(name);
        frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame2.setSize(600, 600);
        frame2.setContentPane(plot2);
        frame2.setVisible(true);
    }

    public static void print(double[] x, double[] y, String name){
        Plot2DPanel plot = new Plot2DPanel();
        plot.addLinePlot("",x, y);
        JFrame frame = new JFrame(name);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setContentPane(plot);
        frame.setVisible(true);
    }
}
